package com.sptokentest.service.ServiceImpl;

import cn.dev33.satoken.stp.StpUtil;
import cn.dev33.satoken.util.SaResult;
import cn.hutool.core.date.DateUtil;
import com.baomidou.dynamic.datasource.annotation.DS;
import com.baomidou.dynamic.datasource.toolkit.DynamicDataSourceContextHolder;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.sptokentest.entity.*;
import com.sptokentest.pj.dto.RoleDto;
import com.sptokentest.mapper.RoleMapper;
import com.sptokentest.service.MenuService;
import com.sptokentest.service.RoleMenuService;
import com.sptokentest.service.RoleService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.sptokentest.service.UserRoleService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author young
 * @since 2023年01月14日
 */
@Service
public class RoleServiceImpl extends ServiceImpl<RoleMapper, Role> implements RoleService {

    @Autowired
    private RoleService roleService;
    @Autowired
    private RoleMenuService roleMenuService;
    @Autowired
    private MenuService menuService;
    @Autowired
    private UserRoleService userRoleService;
    @Autowired
    private RoleMapper roleMapper;
    @Override
    public SaResult addRole(RoleDto roleDto) {
        //检查权限是否为空
        if(roleDto.getPerIds().size()==0){
            return SaResult.error("请给角色分配权限");
        }
        //检查per字段是否唯一，roleName是否唯一
        LambdaQueryWrapper<Role> lqw2 = new LambdaQueryWrapper<>();
        lqw2.eq(Role::getRoleName,roleDto.getRoleName()).or().eq(Role::getPer,roleDto.getPer());
        if(roleService.list(lqw2).size()>=1){
            return SaResult.error("角色名称或权限标识符已存在");
        }
        if(StpUtil.getPermissionList(StpUtil.getLoginId()).contains("system:role:add")){
            roleDto.setCreateTime(DateUtil.date().toString());
            roleDto.setUpdateTime(DateUtil.date().toString());
            roleDto.setStatus(roleDto.getStatus());
            roleService.save(roleDto);

            LambdaQueryWrapper<Role> lqw = new LambdaQueryWrapper<>();
            lqw.eq(Role::getPer,roleDto.getPer());
            Role role = roleService.getOne(lqw);
            //将一级菜单加入其中
            List<Long> oneMenu = new ArrayList<>();  //创建一级菜单列表，用于存储一级菜单

            LambdaQueryWrapper<Menu> lqw1 = new LambdaQueryWrapper<>();
            lqw1.isNotNull(Menu::getMid).in(Menu::getMenuId,roleDto.getPerIds()); //只要二级菜单
            List<Menu> menus = menuService.list(lqw1);
            for (Menu menu :
                    menus) {
                oneMenu.add(menu.getMid());
            }

            //将一级菜单列表和二级菜单列表合并
            oneMenu.addAll(roleDto.getPerIds());
            //使用set集合去重
            Set<Long> set = new HashSet<>(oneMenu);
            oneMenu = new ArrayList<>(set);
            //将所有权限保存到数据库中
            for (Long id :
                    oneMenu) {
                RoleMenu roleMenu = new RoleMenu();
                roleMenu.setRoleId(role.getRoleId());
                roleMenu.setMenuId(id);
                roleMenuService.save(roleMenu);
            }

            return SaResult.ok();
        }
        return SaResult.error("对不起，您没有权限");
    }

    @Override
    public SaResult editRole(RoleDto roleDto) {
        //检查权限是否为空
        if(roleDto.getPerIds().size()==0){
            return SaResult.error("请给角色分配权限");
        }
        //检查per字段是否唯一，roleName是否唯一
        LambdaQueryWrapper<Role> lqw3 = new LambdaQueryWrapper<>();
        lqw3.eq(Role::getRoleName,roleDto.getRoleName()).or().eq(Role::getPer,roleDto.getPer());
        if(roleService.list(lqw3).size()>1){
            return SaResult.error("角色名称或权限标识符已存在");
        }
        if(StpUtil.getPermissionList(StpUtil.getLoginId()).contains("system:role:edit")){
            roleDto.setUpdateTime(DateUtil.date().toString());
            //首先将role表更新
            roleService.updateById(roleDto);
            //删除该角色rolemenu表中所有权限
            LambdaQueryWrapper<RoleMenu> lqw1 = new LambdaQueryWrapper<>();
            lqw1.eq(RoleMenu::getRoleId,roleDto.getRoleId());
            roleMenuService.remove(lqw1);
            //将该角色的权限重新添加
            List<Long> oneMenu = new ArrayList<>();  //创建一级菜单列表，用于存储一级菜单
            LambdaQueryWrapper<Menu> lqw2 = new LambdaQueryWrapper<>();
            lqw2.isNotNull(Menu::getMid).in(Menu::getMenuId,roleDto.getPerIds()); //只要二级菜单
            List<Menu> menus = menuService.list(lqw2);
            for (Menu menu :
                    menus) {
                oneMenu.add(menu.getMid());
            }
            //将一级菜单列表和二级菜单列表合并
            oneMenu.addAll(roleDto.getPerIds());
            //使用set集合去重
            Set<Long> set = new HashSet<>(oneMenu);
            oneMenu = new ArrayList<>(set);
            //将所有权限保存到数据库中
            for (Long id :
                    oneMenu) {
                RoleMenu roleMenu = new RoleMenu();
                roleMenu.setRoleId(roleDto.getRoleId());
                roleMenu.setMenuId(id);
                roleMenuService.save(roleMenu);
            }
            return SaResult.ok();
        }
        return SaResult.error("对不起，您没有权限");
    }

    @Override
    public SaResult setStatus(Role role) {
        if(StpUtil.getPermissionList(StpUtil.getLoginId()).contains("system:role:status")){
            role.setUpdateTime(DateUtil.date().toString());
            role.setStatus(role.getStatus()==0 ? 1 : 0);
            roleService.updateById(role);
            return SaResult.ok();
        }
        return SaResult.error("对不起，您没有权限");
    }

    @Override
    public SaResult delete(Long id) {
        if(StpUtil.getPermissionList(StpUtil.getLoginId()).contains("system:role:delete")){
            //如果这个角色当前属于某个用户，则删除失败
            LambdaQueryWrapper<UserRole> lqw1 = new LambdaQueryWrapper<>();
            lqw1.eq(UserRole::getRoleId,id);
            if (userRoleService.list(lqw1).size()!=0){
                return SaResult.error("该角色正在使用，请先删除使用该角色的用户");
            }

            //首先删除roleMenu中的所有roleId为id的数据
            LambdaQueryWrapper<RoleMenu> lqw = new LambdaQueryWrapper<>();
            lqw.eq(RoleMenu::getRoleId,id);
            boolean removeRoleMenu = roleMenuService.remove(lqw);
            //再删除role中的roleId的数据
            boolean removeRole = roleService.removeById(id);
            if(removeRoleMenu && removeRole){
                return SaResult.ok();
            }
            return SaResult.error("删除失败");
        }
        return SaResult.error("对不起，您没有权限");
    }



    @Override
    public SaResult getPage(int page, int pageSize, String rolename) {
        if(StpUtil.getPermissionList(StpUtil.getLoginId()).contains("system:role:query")){
            Page<Role> pageInfo = new Page<>(page,pageSize);
            Long count = roleMapper.selectCount(null);
            int start = (page-1)*pageSize;
            pageInfo.setRecords(roleMapper.selectRolePagesByDerby(start,pageSize));
//            pageInfo.setRecords(roleMapper.selectRolePagesByMysql(start,pageSize));
            pageInfo.setCurrent(page);
            pageInfo.setSize(pageSize);
            pageInfo.setTotal(count);
            pageInfo.setPages((count+pageSize-1)/pageSize);
            if(pageInfo.getPages()<page){
                pageInfo.setCurrent(pageInfo.getPages());
                this.getPage(page,pageSize,rolename);
            }
            return SaResult.data(pageInfo);
        }
       return SaResult.error("对不起，您没有权限");
    }
}
